package com.angel.resourceBundle.contexts;

import com.angel.resourceBundle.propertyValue.PropertyValue;




/**
 * {@link ResourceBundleContext} was created because of you can extends from him to implements a specific resource bundle application.
 * Here you must decide how is going to create the application labels, and default texts for you application.
 * A default implementation can be the follow:
 * If you have two languages for you application, for example English and Spanish.
 * In the abstract method {@code initializeContext()} you must initialize all the languages in you application, and your key application can be
 * generated by the follow string: [APPLICATIONNAME]_[IDIOM]_[SPECIFIC_STRINGKEY], being:
 * [APPLICATIONNAME]: Your application name.
 * [IDIOM] : Current selected languages.
 * [SPECIFIC_STRINGKEY] A specific string key, for example a label or a text.
 *
 * @author William
 *
 */
public abstract class ResourceBundleContext {

	private static final String DEFAULT_KEY_SEPARATOR = "_";

	private String keySeparator;

	/** Get key value for this context. Generally this context key refers to application key.
	 *
	 * @return a context key.
	 */
	public abstract String getApplicationKey();

	/** Get current language name. Generally it is used for example to generate extended key to find property value.
	 *
	 * @return current language name.
	 */
	public abstract String getCurrentLanguageName();

	public abstract String getResourceBundleManagerType();

	/**
	 *  Initialize all information context.
	 */
	public abstract void initializeContext();

	/** Update property value attributes. It is used to update specific attributes for user property values' implementations.
	 *
	 * @param propertyValue to be update.
	 */
	public abstract void updatePropertyValue(PropertyValue propertyValue);

	public ResourceBundleContext(String keySeparator){
		super();
		this.keySeparator = keySeparator;
	}

	/** Default application constructor.
	 *
	 */
	public ResourceBundleContext(){
		this(DEFAULT_KEY_SEPARATOR);
	}

	/** Generate a extended key for a property key. This extended key is generated for current language name.
	 *
	 * @param propertyKey to generate its extended key.
	 * @return a extended key generated with current language name.
	 */
	public String generateExtendedKey(String propertyKey){
		String KEY_SEPARATOR = this.getKeySeparator();
		String resourceBundleKey = this.generateResourceBundleContextKey();
		String extendedKey = resourceBundleKey + KEY_SEPARATOR;
		extendedKey += this.getCurrentLanguageName() + KEY_SEPARATOR;
		extendedKey += propertyKey;
		return extendedKey.toUpperCase();
	}

	/** Generated an extended key for a property key and a specific language name.
	 *
	 * @param propertyKey to generate its extended key.
	 * @param languageName associated to property key.
	 * @return an extended key generated.
	 */
	public String generateExtendedKey(String propertyKey, String languageName){
		String SEPARATOR_KEY = this.getKeySeparator();
		String resourceBundleKey = this.generateResourceBundleContextKey();
		String extendedKey = resourceBundleKey + SEPARATOR_KEY;
		extendedKey += languageName + SEPARATOR_KEY;
		extendedKey += propertyKey;
		return	extendedKey.toUpperCase();
	}

	/** Generate an extended key array from a properties keys array. Extended keys are generated with current
	 * resource bundle context language.
	 *
	 * @param propertiesKeys array to generated its extended key array.
	 * @return an extended key array.
	 */
	public String[] generateExtendedKey(String[] propertiesKeys){
		int size = propertiesKeys != null ? propertiesKeys.length : 0;
		String[] extendedKeys = new String[size];
		for(int i = 0; i < size; i++){
			extendedKeys[i] = this.generateExtendedKey(propertiesKeys[i]);
		}
		return extendedKeys;
	}

	public String[] generateExtendedKey(String[] propertiesKeys, String languageName){
		int size = propertiesKeys != null ? propertiesKeys.length : 0;
		String[] extendedKeys = new String[size];
		for(int i = 0; i < size; i++){
			extendedKeys[i] = this.generateExtendedKey(propertiesKeys[i], languageName);
		}
		return extendedKeys;
	}


	public String generateResourceBundleContextKey(String languageName){
		String keySeparator = this.getKeySeparator();
		return (this.getApplicationKey() + keySeparator + this.getResourceBundleManagerType() + keySeparator + languageName).toUpperCase();
	}

	/** Generate a resource bundle context key. It is used to find all properties values for a context.
	 * This context key includes current application key and resource bundle manager type.
	 * Context key is generated as:
	 * 		ApplicationKey + keySeparator + ResourceBundleManagerType.
	 *
	 * @return a resource bundle context key.
	 */
	public String generateResourceBundleContextKey(){
		String KEY_SEPARATOR = this.getKeySeparator();
		String resourceBundleContextKey = this.getApplicationKey() + KEY_SEPARATOR;
		resourceBundleContextKey += this.getResourceBundleManagerType();
		return resourceBundleContextKey.toUpperCase();
	}

	/**
	 * @return the keySeparator
	 */
	public String getKeySeparator() {
		return keySeparator;
	}

	/**
	 * @param keySeparator the keySeparator to set
	 */
	protected void setKeySeparator(String keySeparator) {
		this.keySeparator = keySeparator;
	}

	protected String getDefaultSeparator(){
		return DEFAULT_KEY_SEPARATOR;
	}

	public Boolean isResourceBundleManagerType(String resourceBunleContextType) {
		return this.getResourceBundleManagerType().equalsIgnoreCase(resourceBunleContextType);
	}

}
